#include "log.h"
#include <iostream>

LogEvent::LogEvent(std::shared_ptr<Logger> logger, const char* file, int32_t line, uint64_t time, LogLevel::Level level)
                :m_file(file),
                m_line(line),
                m_time(time),
                m_level(level),
                m_logger(logger)
{

}

std::shared_ptr<Logger> LogEvent::GetLogger()
{
    return m_logger;
}

void LogEvent::TimeOutPut(std::ostream& os)
{
    std::string format = "%Y-%m-%d %H:%M:%S";
    struct tm tm;
    localtime_r(&m_time, &tm);
    char buf[64];
    strftime(buf, sizeof(buf), format.c_str(), &tm);
    os << buf << "  ";
}

void LogEvent::LineOutPut(std::ostream& os)
{
    os << ":" << m_line << "   ";
}

void LogEvent::LevelOutPut(std::ostream& os)
{
    os << LogLevel::ToString(m_level) << "   ";
}

void LogEvent::FileOutPut(std::ostream& os)
{
    os << m_file;
}

void LogEvent::ContentOutPut(std::ostream& os)
{
    std::string content = m_ss.str();
    os << content << std::endl;
}

LogEvent::~LogEvent()
{

}

std::stringstream& LogEvent::GetSS()
{
    return m_ss;
}

LogEventWrap::LogEventWrap(LogEvent::ptr e)
    :m_event(e)
{

}

LogEventWrap::~LogEventWrap()
{
    m_event->GetLogger()->Log(m_event->GetLevel(), m_event);
}

void Logger::Log(LogLevel::Level level, LogEvent::ptr event)
{
    event->TimeOutPut(std::cout);
    event->LevelOutPut(std::cout);
    event->FileOutPut(std::cout);
    event->LineOutPut(std::cout);
    event->ContentOutPut(std::cout);
}

Logger::Logger(const std::string& name):m_name(name)
{

}

Logger::ptr LoggerManager::GetLogger(const std::string& name)
{
    auto it = m_loggers.find(name);
    if(it != m_loggers.end())
    {
        return it->second;
    }
    Logger::ptr logger(new Logger(name));
    m_loggers[name] = logger;
    return logger;
}